﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

using ERPStore.Web.Html;
using ERPStore.Web.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.Exporter.Controllers
{
	public class ExporterController : ERPStore.Web.Controllers.StoreController
	{
		public ExporterController(EventBrokR.IPublisher publisher
			, ERPStore.Services.CryptoService cryptoService
			, ERPStore.Services.ICatalogService catalogService)
		{
			this.Publisher = publisher;
			this.CryptoService = cryptoService;
			this.CatalogService = catalogService;
		}

		protected EventBrokR.IPublisher Publisher { get; set; }
		protected ERPStore.Services.CryptoService CryptoService { get; set; }
		protected ERPStore.Services.ICatalogService CatalogService { get; set; }

		public ActionResult Download(string file)
		{
			Logger.Notification("Get {0} from {1} ({2})", file, Request.UserAgent, Request.UserHostAddress);
			var fileName = System.IO.Path.GetFileName(file);
			var ext = System.IO.Path.GetExtension(fileName);
			var mimeType = ext == ".xml" ? "text/xml" : "text/plain";
			return File(string.Format("~/sitemaps/{0}", file), mimeType);
		}

		public ActionResult TrackerRedirect(string key)
		{
			if (key.IsNullOrEmpty())
			{
				Logger.Warn("Comparator redirect with emptykey from {0}:{1}", Request.UserAgent, Request.UserHostAddress);
				return new EmptyResult();
			}
			var tk = new ERPStore.Exporter.Models.TrackKey();
			try
			{
				var crypted = key.Split('?')[0];
				CryptoService.Decrypt(crypted, tk);
			}
			catch(Exception ex)
			{
				ex.Data.Add("url", Request.RawUrl);
				ex.Data.Add("referer", (Request.UrlReferrer != null) ? Request.UrlReferrer.OriginalString : string.Empty);
				ex.Data.Add("IP", Request.UserHostAddress);
				ex.Data.Add("UserAgent", Request.UserAgent);
				Logger.Error(ex);
				return RedirectToERPStoreRoute(ERPStore.Web.Routing.ERPStoreRoutes.HOME);
			}

			var product = CatalogService.GetProductByCode(tk.ProductCode);
			if (product == null)
			{
				Logger.Warn("Comparator redirect with unknown product code {0}", tk.ProductCode);
				return Redirect(Url.HomeHref()); 
			}

			// Add Analytics tracking
			var url = Url.Href(product);
			var existingParameters = Request.Url.GetParameters();
			foreach (string prm in existingParameters.Keys)
			{
				var value = existingParameters[prm];
				if (value != null)
				{
					url = url.AddParameter(prm, value);
				}
			}

			var certid = Guid.NewGuid().ToString().Replace("-","").Left(12);
			var trackedUrl = url.AddParameter("estid", tk.SourceName).AddParameter("certid", certid).AddParameter("estdt", tk.Date);
			string keyword = null;

			if (Request.UrlReferrer != null)
			{
				keyword = new Uri(Request.UrlReferrer.OriginalString).GetSearchKeywords();
				if (keyword != null)
				{
					var buffer = System.Text.Encoding.UTF8.GetBytes(keyword);
					var qre = System.Convert.ToBase64String(buffer);
					url = url.AddParameter("qre", qre);
				}
			}

			bool isNewVisitor = false;
			var @event = new ERPStore.Events.TrackerEvent();
			@event.ActionName = "product";
			@event.ControllerName = "catalog";
			@event.CreationDate = DateTime.Now;
			@event.Model = product;
			@event.Language = (Request.UserLanguages != null && Request.UserLanguages.Length > 0) ? Request.UserLanguages[0] : string.Empty;
			@event.LocalPath = trackedUrl;
			@event.OriginalUrl = string.Format("http://{0}:80{1}", Request.Url.Host.TrimEnd('/'), trackedUrl);
			@event.RawUrl = trackedUrl;
			@event.Referer = (Request.UrlReferrer != null) ? Request.UrlReferrer.OriginalString : string.Empty;
			@event.UserAgent = Request.UserAgent;
			@event.UserHostAddress = Request.UserHostAddress;
			@event.ViewName = "product";
			@event.VisitorId = HttpContext.GetOrCreateVisitorId(out isNewVisitor);
			@event.ResponseStatusCode = 200;
			@event.ExtendedParameters = new List<ERPStore.Models.WebParameter>();
			@event.ExtendedParameters.Add(new ERPStore.Models.WebParameter()
			{
				Type = ERPStore.Models.WebParameterType.ViewData,
				Name = "productId",
				Value = product.Id.ToString(),
			});
			@event.ExtendedParameters.Add(new ERPStore.Models.WebParameter()
			{
				Type = ERPStore.Models.WebParameterType.ViewData,
				Name = "productCode",
				Value = product.Code,
			});

			if (User.Identity.IsAuthenticated)
			{
				@event.UserId = User.CurrentUser.Id;
			}

			Publisher.PublishAsync(@event);

			try
			{
				var catalogDate = new DateTime(Convert.ToInt32(tk.Date.Substring(0, 2)) + 2000, Convert.ToInt32(tk.Date.Substring(2, 2)), Convert.ToInt32(tk.Date.Substring(4)));
				var lag = (DateTime.Today - catalogDate).TotalDays;
				if (lag > 3)
				{
					Logger.Warn("{0} days lag detected from catatalog feed for product {1} source {2} ua {3}/{4}", lag, product.Code, tk.SourceName, Request.UserHostAddress, Request.UserAgent);
				}
			}
			catch
			{
			}

			Response.AddHeader(
				"Cache-Control",
				"private, no-cache, no-cache=Set-Cookie, proxy-revalidate");
			Response.AddHeader("Pragma", "no-cache");
			Response.AddHeader("Expires", "Wed, 17 Sep 1975 21:32:10 GMT");
			Response.Buffer = false;

			ViewData.Model = @event;
			ViewBag.Url = url;
			ViewBag.SourceName = tk.SourceName;
			ViewBag.SourceId = tk.SourceId;
			ViewBag.Medium = tk.Medium;
			ViewBag.ProductCode = tk.ProductCode;

			Logger.Debug("SL from({0}) keywords({1}) product({2}) date({3}) medium({4}) ua({5})", tk.SourceName, keyword, tk.ProductCode, tk.Date, tk.Medium, Request.UserAgent);

			return View("ExporterRedirect");
		}

		public ActionResult RedirectToTarget(string targetUrl)
		{
			return RedirectPermanent(targetUrl);
		}
	}
}
